package main

import (
	"gitee.com/ha666/golibs"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/context"
	"github.com/astaxie/beego/logs"
	_ "github.com/astaxie/beego/session/redis"
	_ "ha666web/initial"
	"ha666web/models"
	_ "ha666web/routers"
	"net/http"
	"strings"
	"time"
)

func main() {
	defer recover_panic()
	go update_blacklists()
	beego.InsertFilter("/*", beego.BeforeRouter, filter_blacklist)
	beego.ErrorHandler("404", page_not_found)
	beego.ErrorHandler("401", page_note_permission)
	beego.ErrorHandler("500", server_error_500)
	beego.ErrorHandler("501", server_error_501)
	beego.ErrorHandler("502", server_error_502)
	beego.ErrorHandler("503", server_error_503)
	beego.ErrorHandler("504", server_error_504)
	beego.Run()
}

func recover_panic() {
	if err := recover(); err != nil {
		logs.Error("【recover_panic】ex：%v", err)
	}
}

func update_blacklists() {
	for {
		update_blacklist()
		time.Sleep(time.Minute)
	}
}

func update_blacklist() {
	defer func() {
		if err := recover(); err != nil {
			logs.Error("【update_blacklist】ex:%v", err)
		}
	}()
	for {
		logs.Info("【update_blacklist】开始查询")
		ipblacklists, err := models.GetIpblacklistByStatus(1)
		if err != nil {
			logs.Error("【update_blacklist】err:%s", err.Error())
			time.Sleep(10 * time.Second)
			continue
		}
		if len(ipblacklists) > 0 && len(ipblacklists[0].IP) > 0 {
			for _, ipblack := range ipblacklists {
				if ipblack.ExpireIn > golibs.Unix() {
					golibs.CacheSet("black_ip_"+ipblack.IP, ipblack.ExpireIn)
					logs.Info("【update_blacklist】ip:%s,设置过期时间:%s", ipblack.IP, time.Unix(ipblack.ExpireIn, 0).Format(golibs.Time_TIMEStandard))
				} else {
					golibs.CacheDel("black_ip_" + ipblack.IP)
					ipblack.Status = 0
					ipblack.ExpireIn = golibs.Unix()
					issuccess, err := models.UpdateIpblacklist(ipblack)
					if err != nil {
						logs.Error("【update_blacklist】修改ip:%s,出错:%s", ipblack.IP, err.Error())
						return
					}
					if !issuccess {
						logs.Error("【update_blacklist】修改ip:%s,失败", ipblack.IP)
						return
					}
					logs.Info("【update_blacklist】删除黑名单ip:%s,成功", ipblack.IP)
				}
			}
		}
		time.Sleep(5 * time.Minute)
	}
}

var filter_blacklist = func(ctx *context.Context) {
	ua := strings.ToLower(ctx.Input.UserAgent())
	if strings.Contains(ua, "spider") || strings.Contains(ua, "bot") {
		ctx.Output.Status = 403
		ctx.Output.Body([]byte("禁止爬虫"))
		return
	}
	ip := ctx.Input.IP()
	expirein, ok := golibs.CacheGetInt64("black_ip_" + ip)
	if ok {
		if expirein > golibs.Unix() {
			ctx.Output.Status = 403
			ctx.Output.Body([]byte("黑名单:" + time.Unix(expirein, 0).Format(golibs.Time_TIMEStandard)))
			return
		}
	}
}

func page_not_found(rw http.ResponseWriter, r *http.Request) {
	rw.WriteHeader(404)
	rw.Write([]byte("系统404，请稍后再试！"))
	return
}

func page_note_permission(rw http.ResponseWriter, r *http.Request) {
	rw.WriteHeader(401)
	rw.Write([]byte("系统401，请稍后再试！"))
	return
}

func server_error_500(rw http.ResponseWriter, r *http.Request) {
	rw.WriteHeader(500)
	rw.Write([]byte("系统错误，请稍后再试！"))
	return
}

func server_error_501(rw http.ResponseWriter, r *http.Request) {
	rw.WriteHeader(501)
	rw.Write([]byte("系统错误，请稍后再试！"))
	return
}

func server_error_502(rw http.ResponseWriter, r *http.Request) {
	rw.WriteHeader(502)
	rw.Write([]byte("系统错误，请稍后再试！"))
	return
}

func server_error_503(rw http.ResponseWriter, r *http.Request) {
	rw.WriteHeader(503)
	rw.Write([]byte("系统错误，请稍后再试！"))
	return
}

func server_error_504(rw http.ResponseWriter, r *http.Request) {
	rw.WriteHeader(504)
	rw.Write([]byte("系统错误，请稍后再试！"))
	return
}
